/*
*  Copyright 2019-2023 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.webuser.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import me.zhengjie.utils.FileUtil;
import me.zhengjie.utils.PageResult;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.webuser.domain.WebUsers;
import me.zhengjie.webuser.domain.vo.WebUsersAvatarInfo;
import me.zhengjie.webuser.domain.vo.WebUsersQueryCriteria;
import me.zhengjie.webuser.mapper.WebUsersMapper;
import me.zhengjie.webuser.service.WebUsersService;
import me.zhengjie.webuser.util.AvatarResource;
import me.zhengjie.webuser.util.AvatarUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
* @description 服务实现
* @author meorin
* @date 2024-12-07
**/
@Service
@RequiredArgsConstructor
public class WebUsersServiceImpl extends ServiceImpl<WebUsersMapper, WebUsers> implements WebUsersService {


    private final WebUsersMapper webUsersMapper;

    @Override
    public PageResult<WebUsers> queryAll(WebUsersQueryCriteria criteria, Page<Object> page){
        return PageUtil.toPage(webUsersMapper.findAll(criteria, page));
    }

    @Override
    public List<WebUsers> queryAll(WebUsersQueryCriteria criteria){
        return webUsersMapper.findAll(criteria);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(WebUsers resources) {
        save(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(WebUsers resources) {
        WebUsers webUsers = getById(resources.getId());
        webUsers.copy(resources);
        saveOrUpdate(webUsers);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateInfo(WebUsers resources) {
        // 校验用户是否存在
        WebUsers existUser = webUsersMapper.selectById(resources.getId());
        if (existUser == null) {
            throw new RuntimeException("用户不存在");
        }

        // 更新bio和email
        if (resources.getBio() != null) {
            webUsersMapper.updateBio(resources.getId(), resources.getBio());
        }
        if (resources.getEmail() != null) {
            webUsersMapper.updateEmail(resources.getId(), resources.getEmail());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Integer> ids) {
        removeBatchByIds(ids);
    }

    @Override
    public void download(List<WebUsers> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (WebUsers webUsers : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("Web用户名", webUsers.getUsername());
            map.put("Web用户邮箱", webUsers.getEmail());
            map.put("Web用户密码", webUsers.getPasswordHash());
            map.put("Web用户创建时间", webUsers.getCreatedAt());
            map.put("Web用户上次登陆时间", webUsers.getLastLoginAt());
            map.put("Web用户头像", webUsers.getAvatarUrl());
            map.put("Web用户简介", webUsers.getBio());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public WebUsers findByUsername(String username) {
        return webUsersMapper.findByUsername(username);
    }

    @Override
    public WebUsers findByEmail(String email) {
        return webUsersMapper.findByEmail(email);
    }

    @Override
    public  WebUsers findByEmailOrUsername(String emailOrUsername) {
        return webUsersMapper.findByEmailOrUsername(emailOrUsername);
    }

    private final AvatarUtils avatarUtils;

    @Override
    public void updateAvatar(MultipartFile file, WebUsers resources) {
        try {
            String url = avatarUtils.uploadAvatar(file, resources.getId());
            webUsersMapper.updateAvatar(resources.getId(), url);
        }
        catch (IOException e) {
            throw new RuntimeException("SFTP上传失败: " + e.getMessage(), e);
        }
    }

    @Override
    public ResponseEntity<Resource> getAvatar(WebUsersQueryCriteria criteria, WebRequest webRequest) {
        // 1. 查询用户 ID 和远程路径
        Integer userId;
        String remotePath;
        if (criteria.getId() == null) {
            WebUsersAvatarInfo info = webUsersMapper.getAvatarUrlByUsername(criteria.getUsername());
            if (info == null || info.getAvatarUrl() == null) {
                return ResponseEntity.notFound().build();
            }
            userId = info.getId();
            remotePath = info.getAvatarUrl();
        } else {
            userId = criteria.getId();
            remotePath = webUsersMapper.getAvatarUrlById(userId);
            if (remotePath == null) {
                return ResponseEntity.notFound().build();
            }
        }

        // 2. 获取头像资源（含缓存验证）
        try {
            AvatarResource avatarResource = avatarUtils.downloadAvatar(remotePath, userId);

            // 3. 自动处理 304 响应（同时检查 ETag 和 Last-Modified）
            if (webRequest.checkNotModified(avatarResource.getETag(), avatarResource.getLastModified())) {
                return null; // 由 Spring 自动返回 304
            }

            // 动态创建 Resource
            ByteArrayResource resource = new ByteArrayResource(avatarResource.getData()) {
                @Override
                public String getFilename() {
                    return avatarResource.getFilename();
                }
            };

            // 确定媒体类型
            String ext = FilenameUtils.getExtension(avatarResource.getFilename());
            MediaType mediaType = AvatarUtils.determineMediaType(ext);

            return ResponseEntity.ok()
                    .contentType(mediaType)
                    .eTag(avatarResource.getETag())
                    .lastModified(avatarResource.getLastModified())
                    .body(resource);
        } catch (FileNotFoundException e) {
            return ResponseEntity.notFound().build();
        } catch (IOException e) {
            log.error("头像下载失败", e);
            return ResponseEntity.internalServerError().build();
        }
    }
}